/**
 * Copyright (c) 2019 Coder League
 * All rights reserved.
 *
 * File：ApplicationConfigurer.java
 * History:
 *         2019年6月26日: Initially created, Chrise.
 */
package club.coderleague.cfss.config;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;

import club.coderleague.cfss.controller.common.ReleaseHandleController;
import club.coderleague.cfss.interceptors.SessionInterceptor;
import club.coderleague.data.jpa.config.JpaConfigurer;
import club.coderleague.data.jpa.config.TransactionConfigurer;
import club.coderleague.data.jpa.repository.support.DataRepositoryFactoryBean;

/**
 * 应用程序配置器。
 * @author Chrise
 */
@SpringBootConfiguration
@Import({
		JpaAuditingConfigurer.class, 
		JpaConfigurer.class, 
		RedisConfigurer.class, 
		SessionConfigurer.class, 
		ThreadPoolConfigurer.class, 
		ThymeleafConfigurer.class, 
		TransactionConfigurer.class, 
		WxmpConfigurer.class, 
		ValidatorConfigurer.class})
@EnableJpaRepositories(basePackages = "club.coderleague.cfss.dao", repositoryFactoryBeanClass = DataRepositoryFactoryBean.class)
public class ApplicationConfigurer implements WebMvcConfigurer {
	@Autowired
	private SessionInterceptor sessionInterceptor;
	@Autowired
	private ThreadPoolTaskExecutor taskExecutor;
	
	/**
	 * @see org.springframework.web.servlet.config.annotation.WebMvcConfigurer#addInterceptors(org.springframework.web.servlet.config.annotation.InterceptorRegistry)
	 */
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(this.sessionInterceptor)
				.addPathPatterns("/**")
				.excludePathPatterns("/", "/nr/**")
				.excludePathPatterns("/**/*" + ReleaseHandleController.REQUEST_PATH_SUFFIX);
	}
	
	/**
	 * @see org.springframework.web.servlet.config.annotation.WebMvcConfigurer#configureAsyncSupport(org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer)
	 */
	@Override
	public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
		configurer.setTaskExecutor(this.taskExecutor);
	}
	
	/**
	 * @see org.springframework.web.servlet.config.annotation.WebMvcConfigurer#extendMessageConverters(java.util.List)
	 */
	@Override
	public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
		SimpleModule module = new SimpleModule();
		module.addSerializer(Long.TYPE, ToStringSerializer.instance);
		module.addSerializer(Long.class, ToStringSerializer.instance);
		
		ObjectMapper mapper = new ObjectMapper();
		mapper.registerModule(module);
		
		MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(mapper);
		converters.add(0, converter);
	}
	
	/**
	 * 注册密码编码器。
	 * @author Chrise 2020年12月19日
	 * @return 密码编码器对象。
	 */
	@Bean
	public PasswordEncoder registerPasswordEncoder() {
		return new BCryptPasswordEncoder();
	}
}
